<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Flree Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
 */
//include_once 'base.php';






/**
 * Constructs a Widget_Action.
 *
 * @return Widget_Action
 */
function Widget_Action()
{
	return new Widget_Action();
}





/**
 * A Widget_Action
 *
 */
class Widget_Action
{
	/**
	 * A flat array containing name => value pairs where name can be of the form "param1[param2][param3]".
	 *
	 * @var array $_parameters
	 */
	private $_parameters = array();

	/**
	 * A corresponding icon name.
	 *
	 * @var string
	 */
	private $_icon = '';


	private $isAjax = false;


	static private $_controllerParamName = 'tg';
	static private $_methodParamName = 'idx';



	/**
	 * Recreates the action from the specified url.
	 *
	 * @return Widget_Action
	 */
	public static function fromUrl($url)
	{
		$splitUrl = parse_url($url);
		parse_str($splitUrl['query'], $parameters);

		$action = new Widget_Action();
		$action->setParameters($parameters);

		return $action;
	}

	/**
	 * Recreates the action from the http request.
	 * if parameters are set the request will be filtered by the parameters names
	 *
	 * @return Widget_Action
	 */
	public static function fromRequest()
	{
		$arr = func_get_args();
		if (!empty($arr)) {

			$parameters = array();

			foreach($arr as $param) {
				$parameters[$param] = bab_rp($param);
			}

		} else {
			$parameters = $_GET + $_POST;
		}

		$action = new Widget_Action();
		$action->setParameters($parameters);

		return $action;
	}



	/**
	 * Set controller method
	 * @param 	string			$controller
	 * @param 	string			$method
	 * @return 	Widget_Action
	 */
	public function setMethod($controller, $method, $parameters)
	{
		$this->setParameters($parameters);
		$this->setParameter(self::$_controllerParamName, $controller);
		$this->setParameter(self::$_methodParamName, $method);

		return $this;
	}





	/**
	 * Returns the full name corresponding to the action method.
	 *
	 * @return array
	 */
	public function getFullName()
	{
		return array(self::$_methodParamName, $this->getMethod());
	}


	/**
	 * Returns the controller name corresponding to the action.
	 *
	 * @return string
	 */
	public function getController()
	{
		return $this->getParameter(self::$_controllerParamName);
	}

	/**
	 * Returns the method name corresponding to the action.
	 *
	 * @return string
	 */
	public function getMethod()
	{
		$method = $this->getParameter(self::$_methodParamName);
		if (is_array($method)) {
			$method = array_pop(array_keys($method));
		}

		return $method;
	}

	/**
	 * Returns the parameters of the action.
	 *
	 * @return array
	 */
	public function getParameters()
	{
		return $this->_parameters;
	}


	/**
	 * Returns the value of the specified parameter.
	 *
	 * @param string $name		The name of the parameter.
	 * @return mixed
	 */
	public function getParameter($name)
	{
		return $this->_parameters[$name];
	}

	/**
	 * Checks the existence of the parameter.
	 *
	 * @param string $name
	 * @return bool
	 */
	public function parameterExists($name)
	{
		return array_key_exists($name, $this->_parameters);
	}

	/**
	 * @param string $name
	 * @param string $value
	 * @return Widget_Action
	 */
	public function setParameter($name, $value)
	{
		$this->_parameters[$name] = $value;
		return $this;
	}


	/**
	 * Sets parameters of the action.
	 *
	 * @param array $values		An associative, possibly nested, array of (name => value) pairs.
	 * @return Widget_Action
	 */
	public function setParameters($values)
	{
		$this->_parameters = $values;
		return $this;
	}

	/**
	 * Returns a non-encoded url corresponding to the action.
	 *
	 * @return string		The non-encoded url string correspondig to the action.
	 */
	public function url()
	{
		$url = '';

		foreach ($this->_parameters as $name => $value) {

			if (!is_null($value)) {

				if ('' === $url) {
					$url .= '?';
				} else {
					$url .= '&';
				}

				if (is_array($value)) {
					if ($name === self::$_methodParamName) {
						$value = array_pop(array_keys($value));
					} else {
						$url .= $this->urlAsArray($name, $value);
					}
				} else {

					$url .= urlencode($name) . '=' . urlencode($value);
				}
			}
		}
		return $url;
	}

	/**
	 * @param	string	$name
	 * @param	array	$arr
	 * @return string			URL
	 */
	private function urlAsArray($name, $arr) {

		$params = array();

		foreach($arr as $key => $value) {

			if (!is_null($value)) {
				if (is_array($value)) {
					$params[] = $this->urlAsArray($name.'['.$key.']', $value);
				} else {
					$params[] = urlencode($name.'['.$key.']').'='.urlencode($value);
				}
			}
		}

		return implode('&', $params);
	}



	/**
	 * Sets the action corresponding icon.
	 *
	 * @param string $icon
	 * @return Widget_Action
	 */
	public function setIcon($icon)
	{
		$this->_icon = $icon;
		return $this;
	}

	/**
	 * Returns the action corresponding icon.
	 *
	 * @return string
	 */
	public function getIcon()
	{
		return $this->_icon;
	}
	
	
	/**
	 * Sets whether the action is ajax compliant.
	 *
	 * @param boolean $isAjax
	 * @return Widget_Action
	 */
	public function setAjax($isAjax = true)
	{
		$this->isAjax = $isAjax;
		return $this;
	}


	/**
	 * Returns whether the action is ajax compliant.
	 *
	 * @return boolean
	 */
	public function isAjax()
	{
		return $this->isAjax;
	}
}

